From e8066d6fef48bde3e051d7cdc832f2a583a6ce16 Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Sun, 1 Dec 2019 18:16:09 -0700 Subject: [PATCH] improve format/filter vector validation. (#427) --- defs.h | 7 ++-- filter_vecs.cc | 31 ++++++++++++++---- filterdefs.h | 2 +- main.cc | 21 ++++++------ vecs.cc | 89 +++++++++++++++++++++++++++++++------------------- 5 files changed, 94 insertions(+), 56 deletions(-) diff --git a/defs.h b/defs.h index 2c1bb0ee3..5dee01c2f 100644 --- a/defs.h +++ b/defs.h @@ -983,8 +983,8 @@ void setshort_is_utf8(short_handle h, int is_utf8); #define ARGTYPE_TYPEMASK 0x00000fffU #define ARGTYPE_FLAGMASK 0xfffff000U -#define ARG_NOMINMAX NULL, NULL -#define ARG_TERMINATOR {0, 0, 0, 0, 0, ARG_NOMINMAX, NULL} +#define ARG_NOMINMAX nullptr, nullptr +#define ARG_TERMINATOR {nullptr, nullptr, nullptr, nullptr, 0, ARG_NOMINMAX, nullptr} struct arglist_t { const char* argstring; @@ -1072,7 +1072,8 @@ void assign_option(const char* vecname, arglist_t* ap, const char* val); void disp_vec_options(const char* vecname, arglist_t* ap); void disp_vecs(); void disp_vec(const char* vecname); -int validate_formats(); +bool validate_args(const char* vecname, arglist_t* ap); +bool validate_formats(); void init_vecs(); void exit_vecs(); void disp_formats(int version); diff --git a/filter_vecs.cc b/filter_vecs.cc index 00476b6d8..aca6120a2 100644 --- a/filter_vecs.cc +++ b/filter_vecs.cc @@ -43,7 +43,6 @@ #include "gbversion.h" #include "inifile.h" -#include // for QList #include // for QString #include // for QStringList #include // for QVector<>::iterator, QVector @@ -316,12 +315,6 @@ disp_filter_vec(const char* vecname) } } -static bool -alpha(const fl_vecs_t& a, const fl_vecs_t& b) -{ - return case_ignore_strcmp(a.desc, b.desc) < 0; -} - static void disp_help_url(const fl_vecs_t& vec, arglist_t* arg) { @@ -362,6 +355,11 @@ void disp_filters(int version) { auto sorted_filter_vec_list = filter_vec_list; + + auto alpha = [](const fl_vecs_t& a, const fl_vecs_t& b)->bool { + return case_ignore_strcmp(a.desc, b.desc) < 0; + }; + std::sort(sorted_filter_vec_list.begin(), sorted_filter_vec_list.end(), alpha); switch (version) { @@ -380,3 +378,22 @@ disp_filters(int version) ; } } + +static bool +validate_filter_vec(const fl_vecs_t& vec) +{ + bool ok = validate_args(vec.name, vec.vec->get_args()); + + return ok; +} + +bool validate_filters() +{ + bool ok = true; + + for (const auto& vec : filter_vec_list) { + ok = validate_filter_vec(vec) && ok; + } + + return ok; +} diff --git a/filterdefs.h b/filterdefs.h index 4cfc5b4f5..cfed0ed94 100644 --- a/filterdefs.h +++ b/filterdefs.h @@ -50,10 +50,10 @@ struct filter_vecs_t { Filter* find_filter_vec(const char* const, const char**); void free_filter_vec(Filter*); void disp_filters(int version); -void disp_filter(const char* vecname); void disp_filter_vec(const char* vecname); void disp_filter_vecs(); void init_filter_vecs(); void exit_filter_vecs(); +bool validate_filters(); #endif // FILTERDEFS_H_INCLUDED_ diff --git a/main.cc b/main.cc index f87a31fbd..fd85021be 100644 --- a/main.cc +++ b/main.cc @@ -65,14 +65,11 @@ public: QStringList qargs; public: - QargStackElement() - = default; + QargStackElement() = default; - QargStackElement(int p_argn, const QStringList& p_qargs) - { - argn = p_argn; - qargs = p_qargs; - } + QargStackElement(int p_argn, const QStringList& p_qargs) : + argn{p_argn}, qargs{p_qargs} + {} }; static QStringList @@ -203,7 +200,6 @@ signal_handler(int sig) static int run(const char* prog_name) { - int c; int argn; ff_vecs_t* ivecs = nullptr; ff_vecs_t* ovecs = nullptr; @@ -262,7 +258,7 @@ run(const char* prog_name) return 0; } - c = qargs.at(argn).size() > 1 ? qargs.at(argn).at(1).toLatin1() : '\0'; + int c = qargs.at(argn).size() > 1 ? qargs.at(argn).at(1).toLatin1() : '\0'; if (qargs.at(argn).size() > 2) { opt_version = qargs.at(argn).at(2).digitValue(); @@ -453,8 +449,11 @@ run(const char* prog_name) /* * Undocumented '-@' option for test. */ - case '@': - return validate_formats(); + case '@': { + bool format_ok = validate_formats(); + bool filter_ok = validate_filters(); + return (format_ok && filter_ok)? 0 : 1; + } /* * Undocumented '-vs' option for GUI wrappers. diff --git a/vecs.cc b/vecs.cc index 578f23264..4cd6b8078 100644 --- a/vecs.cc +++ b/vecs.cc @@ -31,10 +31,11 @@ #include "defs.h" #include "gbversion.h" // for WEB_DOC_DIR #include "inifile.h" // for inifile_readstr +#include "src/core/logging.h" // for Warning #include "xcsv.h" // for XcsvFile, xcsv_file, xcsv_read_internal_style, xcsv_setup_internal_style -#define MYNAME "vecs.c" +#define MYNAME "vecs" struct vecs_t { ff_vecs_t* vec; @@ -1110,7 +1111,7 @@ init_vecs() } } -int +static int is_integer(const char* c) { return isdigit(c[0]) || ((c[0] == '+' || c[0] == '-') && isdigit(c[1])); @@ -1125,11 +1126,6 @@ exit_vecs() } if (vec.vec->args) { for (auto ap = vec.vec->args; ap->argstring; ap++) { - if (ap->defaultvalue && - (ap->argtype == ARGTYPE_INT) && - ! is_integer(ap->defaultvalue)) { - warning("%s: not an integer\n", ap->argstring); - } if (ap->argvalptr) { xfree(ap->argvalptr); *ap->argval = ap->argvalptr = nullptr; @@ -1296,7 +1292,7 @@ find_vec(const char* vecname, const char** opts) } #if CSVFMTS_ENABLED - // xcsv_setup_internal_style( NULL ); + // xcsv_setup_internal_style( nullptr ); #endif // CSVFMTS_ENABLED xfree(v); vec.vec->name = vec.name; /* needed for session information */ @@ -1411,22 +1407,12 @@ get_option(const char* iarglist, const char* argname) return rval; } -/* - * Display the available formats in a format that's easy for humans to - * parse for help on available command line options. - */ -static bool -alpha(const vecs_t& a, const vecs_t& b) -{ - return case_ignore_strcmp(a.desc, b.desc) < 0; -} - /* * Smoosh the vecs list and style lists together and sort them * alphabetically. Returns an allocated copy of a style_vecs_array * that's populated and sorted. */ -QVector +static QVector sort_and_unify_vecs() { QVector svp; @@ -1480,6 +1466,14 @@ sort_and_unify_vecs() svp.append(uvec); } + /* + * Display the available formats in a format that's easy for humans to + * parse for help on available command line options. + */ + auto alpha = [](const vecs_t& a, const vecs_t& b)->bool { + return case_ignore_strcmp(a.desc, b.desc) < 0; + }; + /* Now that we have everything in an array, alphabetize them */ std::sort(svp.begin(), svp.end(), alpha); @@ -1660,74 +1654,101 @@ disp_formats(int version) } } +bool validate_args(const char* vecname, arglist_t* ap) +{ + bool ok = true; + + for (; ap && ap->argstring; ap++) { + if (ap->argtype == ARGTYPE_INT) { + if (ap->defaultvalue && + ! is_integer(ap->defaultvalue)) { + Warning() << vecname << "Int option" << ap->argstring << "default value" << ap->defaultvalue << "is not an integer."; + ok = false; + } + if (ap->minvalue && + ! is_integer(ap->minvalue)) { + Warning() << vecname << "Int option" << ap->argstring << "minimum value" << ap->minvalue << "is not an integer."; + ok = false; + } + if (ap->maxvalue && + ! is_integer(ap->maxvalue)) { + Warning() << vecname << "Int option" << ap->argstring << "maximum value" << ap->maxvalue << "is not an integer."; + ok = false; + } + } + } + + return ok; +} + static bool validate_vec(const vecs_t& vec) { - bool ok = true; + bool ok = validate_args(vec.name, vec.vec->args); if (!((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_write)) { if (vec.vec->wr_init != nullptr) { - printf("ERROR no write capability but non-null wr_init %s\n", vec.name); + Warning() << "ERROR no write capability but non-null wr_init %s\n" << vec.name; ok = false; } } if (!((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_read)) { if (vec.vec->rd_init != nullptr) { - printf("ERROR no read capbility but non-null rd_init %s\n", vec.name); + Warning() << "ERROR no read capability but non-null rd_init %s\n" << vec.name; ok = false; } } if ((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_write) { if (vec.vec->wr_init == nullptr) { - printf("ERROR write capability but null wr_init %s\n", vec.name); + Warning() << "ERROR write capability but null wr_init %s\n" << vec.name; ok = false; } } if ((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_read) { if (vec.vec->rd_init == nullptr) { - printf("ERROR read capability but null rd_init %s\n", vec.name); + Warning() << "ERROR read capability but null rd_init %s\n" << vec.name; ok = false; } } if (vec.vec->wr_init != nullptr) { if (vec.vec->write == nullptr) { - printf("ERROR nonnull wr_init but null write %s\n", vec.name); + Warning() << "ERROR nonnull wr_init but null write %s\n" << vec.name; ok = false; } if (vec.vec->wr_deinit == nullptr) { - printf("ERROR nonnull wr_init but null wr_deinit %s\n", vec.name); + Warning() << "ERROR nonnull wr_init but null wr_deinit %s\n" << vec.name; ok = false; } } if (vec.vec->wr_init == nullptr) { if (vec.vec->write != nullptr) { - printf("ERROR null wr_init with non-null write %s\n", vec.name); + Warning() << "ERROR null wr_init with non-null write %s\n" << vec.name; ok = false; } if (vec.vec->wr_deinit != nullptr) { - printf("ERROR null wr_init with non-null wr_deinit %s\n", vec.name); + Warning() << "ERROR null wr_init with non-null wr_deinit %s\n" << vec.name; ok = false; } } if (vec.vec->rd_init != nullptr) { if (vec.vec->read == nullptr) { - printf("ERROR nonnull rd_init but null read %s\n", vec.name); + Warning() << "ERROR nonnull rd_init but null read %s\n" << vec.name; ok = false; } if (vec.vec->rd_deinit == nullptr) { - printf("ERROR nonnull rd_init but null rd_deinit %s\n", vec.name); + Warning() << "ERROR nonnull rd_init but null rd_deinit %s\n" << vec.name; ok = false; } } if (vec.vec->rd_init == nullptr) { if (vec.vec->read != nullptr) { - printf("ERROR null rd_init with non-null read %s\n", vec.name); + Warning() << "ERROR null rd_init with non-null read %s\n" << vec.name; ok = false; } if (vec.vec->rd_deinit != nullptr) { - printf("ERROR null rd_init with non-null rd_deinit %s\n", vec.name); + Warning() << "ERROR null rd_init with non-null rd_deinit %s\n" << vec.name; ok = false; } } @@ -1735,7 +1756,7 @@ validate_vec(const vecs_t& vec) return ok; } -int validate_formats() +bool validate_formats() { bool ok = true; @@ -1743,5 +1764,5 @@ int validate_formats() ok = validate_vec(vec) && ok; } - return ok? 0 : 1; + return ok; } -- 2.30.2